package com.wpml.netty.rpc.server;

import com.wpml.netty.rpc.Dispatcher;
import com.wpml.netty.rpc.common.MyBody;
import com.wpml.netty.rpc.common.MyHeader;
import com.wpml.netty.rpc.common.PackMsg;
import com.wpml.netty.rpc.util.SerDerUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

public class ServerRequestHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        PackMsg reqPkg = (PackMsg) msg;

//        System.out.println("ServerRequestHandler reqPkg： " + reqPkg);

//        String ioThreadName = Thread.currentThread().getName();
        ctx.executor().parent().next().execute(() -> {
//        ctx.executor().execute(() -> {

            String serviceName = reqPkg.getContent().getName();
            String methodName = reqPkg.getContent().getMethodName();

            Object obj = Dispatcher.invokeMap.get(serviceName);
            Class<?> clazz = obj.getClass();
            Object res = null;
            try {
                Method method = clazz.getMethod(methodName, reqPkg.getContent().getParameterTypes());
                res = method.invoke(obj, reqPkg.getContent().getArgs());
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }


//            String execThreadName = Thread.currentThread().getName();
//            String res = "ioThreadName : " + ioThreadName + "  execThreadName : " + execThreadName + "  from : " + reqPkg.getContent().getArgs()[0];
//            System.out.println("ServerRequestHandler 调用方法返回值 : " + res);
            MyBody body = MyBody.builder()
                    .res(res)
                    .build();
            byte[] bodyByte = SerDerUtil.ser(body);

            MyHeader header = MyHeader.builder()
                    .requestID(reqPkg.getHeader().getRequestID())
                    .flag(0x14141424)
                    .dataLen(bodyByte.length)
                    .build();

            byte[] headerByte = SerDerUtil.ser(header);
            ByteBuf respBuf = PooledByteBufAllocator.DEFAULT.buffer(headerByte.length + bodyByte.length);
            respBuf.writeBytes(headerByte);
            respBuf.writeBytes(bodyByte);

            ctx.writeAndFlush(respBuf);
        });



    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
        System.out.println("client " + address.getPort() + " 连接关闭");
    }


}
